#!/usr/bin/env python3
"""
智能体示例

这个示例展示了：
1. 智能体如何理解用户意图
2. 智能体如何选择合适的工具
3. 智能体如何组合多个工具完成复杂任务
4. 智能体的推理过程展示
"""

import sys
import os
from pathlib import Path
from typing import List

# 添加项目根目录到Python路径
project_root = Path(__file__).parent.parent
sys.path.append(str(project_root))

from langchain_core.messages import HumanMessage, AIMessage

from rich.console import Console
from rich.panel import Panel
from rich.prompt import Prompt
from rich.live import Live
from rich.spinner import Spinner
from rich.table import Table

from chains.agent_chain import smart_agent, tool_demo_agent
from config.settings import settings

console = Console()

def display_welcome():
    """显示欢迎信息"""
    welcome_text = """
🤖 LangChain 智能体示例

智能体是LangChain的核心功能之一，它能够：
- 理解复杂的用户请求
- 自动选择合适的工具
- 组合多个工具完成复杂任务
- 提供详细的推理过程

本示例将展示：
1. 智能体的基本对话
2. 工具选择和使用
3. 多步骤任务执行
4. 错误处理和恢复
5. 推理过程展示

输入 'quit' 退出，输入 'help' 查看可用命令
    """
    
    panel = Panel(
        welcome_text.strip(),
        title="🤖 智能体示例",
        border_style="blue",
        padding=(1, 2)
    )
    
    console.print(panel)
    console.print()

def show_agent_capabilities():
    """展示智能体能力"""
    console.print("[bold green]🚀 智能体能力展示[/bold green]\n")
    
    if not smart_agent.is_ready():
        console.print("[red]❌ 智能体未准备就绪[/red]")
        return
    
    # 显示可用工具
    tools = smart_agent.get_available_tools()
    tool_descriptions = smart_agent.get_tool_descriptions()
    
    table = Table(title="智能体可用工具")
    table.add_column("工具名称", style="cyan", no_wrap=True)
    table.add_column("描述", style="white")
    
    for tool_name in tools:
        description = tool_descriptions.get(tool_name, "无描述")
        table.add_row(tool_name, description)
    
    console.print(table)
    console.print(f"\n智能体已加载 {len(tools)} 个工具")

def demo_predefined_tasks():
    """演示预定义任务"""
    console.print("\n[bold green]📋 预定义任务演示[/bold green]\n")
    
    if not smart_agent.is_ready():
        console.print("[red]❌ 智能体未准备就绪[/red]")
        return
    
    # 预定义的演示任务
    demo_tasks = [
        {
            "name": "搜索任务",
            "query": "搜索一下LangChain的最新消息",
            "description": "演示智能体如何使用搜索工具获取信息"
        },
        {
            "name": "计算任务", 
            "query": "计算一下 25 * 4 + 100 的结果",
            "description": "演示智能体如何使用计算器工具"
        },
        {
            "name": "时间查询",
            "query": "现在是几点？",
            "description": "演示智能体如何获取当前时间"
        },
        {
            "name": "组合任务",
            "query": "帮我计算一下 50*3 的结果，然后搜索一下这个数字的含义",
            "description": "演示智能体如何组合多个工具完成复杂任务"
        },
        {
            "name": "文档处理",
            "query": "帮我总结一下这段文本：人工智能技术正在快速发展。机器学习和深度学习已经在各个领域取得了显著进展。LangChain作为一个强大的框架，为开发者提供了构建AI应用的便利工具。",
            "description": "演示智能体如何处理文档和文本"
        }
    ]
    
    for i, task in enumerate(demo_tasks, 1):
        console.print(f"\n[bold yellow]{i}. {task['name']}[/bold yellow]")
        console.print(f"[dim]{task['description']}[/dim]")
        console.print(f"[cyan]用户输入:[/cyan] {task['query']}")
        
        # 询问是否执行
        if Prompt.ask("是否执行此任务？", choices=["y", "n"], default="y") == "y":
            console.print("\n[dim]🤖 智能体正在思考和执行...[/dim]")
            
            # 执行任务
            with Live(Spinner("dots", "处理中..."), console=console):
                result = smart_agent.run(task['query'])
            
            # 显示结果
            result_panel = Panel(
                result,
                title="🤖 智能体响应",
                border_style="green",
                padding=(1, 2)
            )
            console.print(result_panel)
        
        # 询问是否继续
        if i < len(demo_tasks):
            if Prompt.ask("\n继续下一个任务？", choices=["y", "n"], default="y") == "n":
                break

def interactive_agent_chat():
    """交互式智能体对话"""
    console.print("\n[bold green]💬 交互式智能体对话[/bold green]\n")
    
    if not smart_agent.is_ready():
        console.print("[red]❌ 智能体未准备就绪[/red]")
        return
    
    console.print("[cyan]开始与智能体对话...[/cyan]")
    console.print("[dim]提示：智能体可以使用工具来帮助回答问题[/dim]")
    console.print("[dim]输入 'quit' 退出对话[/dim]\n")
    
    chat_history = []
    
    while True:
        try:
            # 获取用户输入
            user_input = Prompt.ask("[bold blue]用户[/bold blue]").strip()
            
            if not user_input:
                continue
            
            if user_input.lower() in ['quit', 'exit', '退出']:
                console.print("[cyan]对话结束[/cyan]")
                break
            
            # 特殊命令处理
            if user_input.lower() == 'help':
                show_help_commands()
                continue
            
            if user_input.lower() == 'tools':
                show_agent_capabilities()
                continue
            
            if user_input.lower() == 'clear':
                chat_history = []
                console.print("[yellow]对话历史已清除[/yellow]")
                continue
            
            # 添加到历史
            chat_history.append(HumanMessage(content=user_input))
            
            # 调用智能体
            console.print("\n[dim]🤖 智能体正在思考...[/dim]")
            
            with Live(Spinner("dots", "思考中..."), console=console):
                response = smart_agent.run(user_input, chat_history)
            
            # 显示响应
            response_panel = Panel(
                response,
                title="🤖 智能体",
                border_style="green",
                padding=(1, 2)
            )
            console.print(response_panel)
            
            # 添加到历史
            chat_history.append(AIMessage(content=response))
            
            # 保持历史长度合理
            if len(chat_history) > 10:
                chat_history = chat_history[-8:]  # 保留最近的8条消息
            
            console.print()
        
        except KeyboardInterrupt:
            console.print("\n[cyan]对话已退出[/cyan]")
            break
        
        except Exception as e:
            console.print(f"\n[red]对话出错: {str(e)}[/red]")

def show_help_commands():
    """显示帮助命令"""
    help_text = """
可用命令：
- help: 显示此帮助信息
- tools: 显示可用工具列表
- clear: 清除对话历史
- quit/exit: 退出对话

智能体使用示例：
- "搜索一下Python编程教程"
- "计算 123 + 456 等于多少"
- "现在几点了？"
- "帮我总结这篇文章：[文章内容]"
- "先帮我搜索天气，然后计算一下今天的日期"
    """
    
    help_panel = Panel(
        help_text.strip(),
        title="帮助信息",
        border_style="yellow",
        padding=(1, 2)
    )
    console.print(help_panel)

def demonstrate_reasoning_process():
    """演示推理过程"""
    console.print("\n[bold green]🧠 推理过程演示[/bold green]\n")
    
    if not smart_agent.is_ready():
        console.print("[red]❌ 智能体未准备就绪[/red]")
        return
    
    console.print("这个演示将展示智能体的推理过程：")
    console.print("- 如何理解用户意图")
    console.print("- 如何选择合适的工具")
    console.print("- 如何处理工具结果")
    console.print("- 如何生成最终回答\n")
    
    # 复杂任务示例
    complex_query = "我想知道现在的时间，然后帮我计算从现在到下午6点还有多少小时"
    
    console.print(f"[cyan]复杂任务示例:[/cyan] {complex_query}")
    console.print("\n[dim]观察智能体如何分解和执行这个任务...[/dim]\n")
    
    # 执行并显示过程
    with Live(Spinner("dots", "智能体正在推理..."), console=console):
        result = smart_agent.run(complex_query)
    
    result_panel = Panel(
        result,
        title="🧠 智能体推理结果",
        border_style="magenta",
        padding=(1, 2)
    )
    console.print(result_panel)

def show_agent_limitations():
    """展示智能体的限制"""
    console.print("\n[bold green]⚠️ 智能体限制说明[/bold green]\n")
    
    limitations = [
        {
            "标题": "工具依赖性",
            "描述": "智能体的能力完全依赖于可用的工具，没有工具就无法执行相应任务"
        },
        {
            "标题": "推理复杂度",
            "描述": "对于非常复杂的多步骤推理，可能会出现错误或遗漏"
        },
        {
            "标题": "上下文限制",
            "描述": "受模型上下文长度限制，长对话可能会丢失早期信息"
        },
        {
            "标题": "错误传播",
            "描述": "如果某个工具出错，可能会影响整个任务的执行"
        },
        {
            "标题": "成本考虑",
            "描述": "每次工具调用都会消耗API调用次数，需要考虑成本"
        }
    ]
    
    for limitation in limitations:
        panel = Panel(
            limitation["描述"],
            title=f"⚠️ {limitation['标题']}",
            border_style="yellow",
            padding=(1, 2)
        )
        console.print(panel)

def main():
    """主函数"""
    console.print("[bold cyan]🤖 LangChain 智能体示例[/bold cyan]\n")
    
    # 验证配置
    if not settings.validate_configuration():
        console.print("[red]配置验证失败，请检查您的设置[/red]")
        return
    
    display_welcome()
    
    # 示例菜单
    examples = [
        ("智能体能力展示", show_agent_capabilities),
        ("预定义任务演示", demo_predefined_tasks),
        ("推理过程演示", demonstrate_reasoning_process),
        ("交互式对话", interactive_agent_chat),
        ("限制说明", show_agent_limitations)
    ]
    
    while True:
        console.print("\n" + "="*60)
        console.print("[bold yellow]请选择要运行的示例：[/bold yellow]")
        
        for i, (name, _) in enumerate(examples, 1):
            console.print(f"{i}. {name}")
        
        console.print("0. 退出")
        
        try:
            choice = Prompt.ask("\n请输入选项", choices=[str(i) for i in range(len(examples) + 1)])
            choice = int(choice)
            
            if choice == 0:
                console.print("[cyan]再见！[/cyan]")
                break
            
            if 1 <= choice <= len(examples):
                console.print(f"\n{'='*60}")
                console.print(f"运行: {examples[choice-1][0]}")
                console.print('='*60)
                
                try:
                    examples[choice-1][1]()
                except Exception as e:
                    console.print(f"[red]示例运行失败: {str(e)}[/red]")
            else:
                console.print("[red]无效选项[/red]")
                
        except (ValueError, KeyboardInterrupt):
            console.print("\n[cyan]程序已退出[/cyan]")
            break
        except Exception as e:
            console.print(f"[red]发生错误: {str(e)}[/red]")

if __name__ == "__main__":
    main() 